﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace YArchitech.Temp
{
	public class HYSystem : HYObject, IHYXmlSerial, IDisposable
	{
		public HashSet<HYMEPObject> Objects
		{
			get
			{
				return this.m_Objects;
			}
		}

		public HYMEPObject Root
		{
			get
			{
				return this.m_RootObject;
			}
		}

		public List<HYBranch> Branches
		{
			get
			{
				if (this.m_Branches == null)
				{
					this.BuildBranches();
				}
				return this.m_Branches;
			}
		}

		public List<HYPipeline> Pipelines
		{
			get
			{
				if (this.m_Pipelines == null)
				{
					this.GetAllPipelines(out this.m_Pipelines);
				}
				return this.m_Pipelines;
			}
		}

		public bool IsEmpty
		{
			get
			{
				return this.m_Objects == null || this.m_Objects.Count == 0;
			}
		}

		public string Name { get; set; }

		public HYBranch MaxResistanceBranch
		{
			get
			{
				if (this.m_maxResistanceBranch == null)
				{
					this.GetMaxResistanceBranch();
				}
				return this.m_maxResistanceBranch;
			}
		}

		public HYSystem()
		{
			this.m_Objects = new HashSet<HYMEPObject>();
		}

		public void Dispose()
		{
			this.m_Objects.Clear();
		}

		public int GetAllPipelines(out List<HYPipeline> Pipelines)
		{
			Pipelines = new List<HYPipeline>();
			foreach (HYMEPObject hymepobject in from pl in this.m_Objects
			where pl is HYPipeline
			orderby pl.Index
			select pl)
			{
				Pipelines.Add(hymepobject as HYPipeline);
			}
			return Pipelines.Count;
		}

		public int GetAllTerminals(out List<HYMEPObject> terminals)
		{
			terminals = new List<HYMEPObject>(from hyObj in this.m_Objects
			where hyObj.Next == null
			select hyObj);
			return terminals.Count;
		}

		public override void WriteXml(XElement xe)
		{
			xe.SetAttributeValue("Name", this.Name);
			XElement xelement = new XElement("Objects");
			foreach (HYMEPObject hymepobject in this.m_Objects)
			{
				XElement xelement2 = new XElement(hymepobject.Name);
				hymepobject.WriteXml(xelement2);
				xelement.Add(xelement2);
			}
			xe.Add(xelement);
			XElement xelement3 = new XElement("Branches");
			foreach (HYBranch hybranch in this.m_Branches)
			{
				XElement xelement4 = new XElement("Branch");
				hybranch.WriteXml(xelement4);
				xelement3.Add(xelement4);
			}
			xe.Add(xelement3);
		}

		public override void ReadXml(XElement xe)
		{
			this.Name = xe.GetStringAttribute("Name", "HYSystem");
		}

		public void Reomve(HYMEPObject hyObj)
		{
			this.m_Objects.Remove(hyObj);
		}

		public void SetRootObject(HYMEPObject hyObj)
		{
			this.m_RootObject = hyObj;
			this.Add(hyObj);
		}

		public bool Add(HYMEPObject hyObj)
		{
			return this.m_Objects.Add(hyObj);
		}

		public HYMEPObject FindObjectById(int id)
		{
			return this.m_Objects.First((HYMEPObject hyObj) => hyObj.Id == id);
		}

		public HYMEPObject FindObjectByIndex(int index)
		{
			return this.m_Objects.First((HYMEPObject hyObj) => hyObj.Index == index);
		}

		public virtual bool BuildBranches()
		{
			this.m_Branches = new List<HYBranch>();
			List<HYMEPObject> list;
			if (this.GetAllTerminals(out list) == 0)
			{
				return false;
			}
			foreach (HYMEPObject terminal in list)
			{
				HYBranch item = HYBranch.BuildBranch(terminal, this.m_Objects);
				this.m_Branches.Add(item);
			}
			this.m_Branches.Sort(new HYBranchLengthComparer());
			int num = 1;
			foreach (HYBranch hybranch in this.m_Branches)
			{
				hybranch.Index = num++;
			}
			return true;
		}

		public virtual bool BuildIndex()
		{
			int num = 1;
			this.m_RootObject.RebuildIndex(ref num);
			return true;
		}

		public HYBranch GetLongestBranch()
		{
			if (this.m_Branches == null)
			{
				this.BuildBranches();
			}
			return (from branch in this.m_Branches
			orderby branch.Length descending
			select branch).First<HYBranch>();
		}

		public HYBranch GetMaxResistanceBranch()
		{
			if (this.m_Branches == null)
			{
				return null;
			}
			IOrderedEnumerable<HYBranch> source = from branch in this.m_Branches
			orderby branch.Resistance descending
			select branch;
			this.m_maxResistanceBranch = source.First<HYBranch>();
			return this.m_maxResistanceBranch;
		}

		public HYBranch GetMostUnbalancedBranch()
		{
			if (this.m_Branches == null)
			{
				return null;
			}
			return (from branch in this.m_Branches
			orderby branch.UnbalanceRate descending
			select branch).First<HYBranch>();
		}

		protected HashSet<HYMEPObject> m_Objects;

		protected HYMEPObject m_RootObject;

		protected List<HYBranch> m_Branches;

		protected List<HYPipeline> m_Pipelines;

		private HYBranch m_maxResistanceBranch;
	}
}
